package com.gf.user.controller;

import java.awt.image.BufferedImage;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.dominicsayers.isemail.dns.DNSLookupException;
import com.gf.base.controller.BasicController;
import com.gf.base.type.Activity;
import com.gf.common.bean.Page;
import com.gf.common.constant.Constants;
import com.gf.common.constant.ViewPaths;
import com.gf.common.exception.NotOperationEexception;
import com.gf.common.staticer.AboutContentHelper;
import com.gf.common.staticer.AllNicknamesAndUID;
import com.gf.common.staticer.MessageRemainsHelper;
import com.gf.common.util.CertCodeHelper;
import com.gf.common.util.MailHelper;
import com.gf.common.util.WebHelper;
import com.gf.event.service.EventService;
import com.gf.exam.service.AnswerService;
import com.gf.exam.service.ExamCellService;
import com.gf.user.model.Ticket;
import com.gf.user.model.User;
import com.gf.user.service.TicketService;
import com.gf.user.service.UserBaseService;
import com.gf.user.service.UserService;

/**
 * 对用户一些基本操作的处理 如登入，注册,找回密码 , 登出。。。
 * 
 * "redirect:"+后不是相应的JSP地址，而是请求地址，然后映射到相应的处理方法上，而后还得加上相应的后缀（.html）
 * 
 * @author Colonel
 * 
 */
@Controller
@RequestMapping("/base")
public class BaseUserController extends BasicController {
	private static final Log logger = LogFactory
			.getLog(BaseUserController.class);

	@Autowired
	private UserBaseService userBaseService;

	@Autowired
	private ExamCellService examCellService;

	@Autowired
	private TicketService ticketService;

	@Autowired
	private UserService userService;

	@Autowired
	private AnswerService answerService;

	@Autowired
	private EventService eventService;

	/**
	 * 首页
	 * 
	 * @return
	 */
	@RequestMapping(value = "/index", method = RequestMethod.GET)
	public ModelAndView visit() {
		ModelAndView mvc = new ModelAndView();
		mvc.setViewName(ViewPaths.VISIT_INDEX_VIEW);
		Page page = examCellService.getAll(5, 1);
		Page answerPage = eventService.getqueryRecentEvent(1, 5);
		User user = WebHelper.getSessionAttribute(Constants.SESSION_USER);
		if (user != null) {
			int messageCount = MessageRemainsHelper.getRemains(user.getId());
			mvc.addObject("messageCount", messageCount);
		}
		int totalAnswer = answerService.getTotalCount();
		mvc.addObject("user", user);
		mvc.addObject("page", page);
		mvc.addObject("answerPage", answerPage);
		mvc.addObject("totalAnswer", totalAnswer);
		return mvc;
	}

	/**
	 * 用户登入前
	 * 
	 * @return
	 */
	@RequestMapping(value = "/login", method = RequestMethod.GET)
	public ModelAndView loginBefore(String url) {

		logger.info("before login: " + url);

		// 存到session里
		if (url != null && !url.equals("")) {
			WebHelper.setSessionAttribute(Constants.SESSION_BEFORE_LOGIN_URL,
					url);
		}

		ModelAndView mvc = new ModelAndView();
		mvc.setViewName(ViewPaths.LOGIN_VIEW);
		return mvc;
	}

	/**
	 * 用户登入提交
	 * 
	 * @return
	 */
	@RequestMapping(value = "/login", method = RequestMethod.POST)
	public @ResponseBody
	String loginAfter(String email, String password) {
		logger.info("login:" + email + "  " + password);

		User user = new User();
		// ModelAndView mvc = new ModelAndView();

		user = userBaseService.isUserExist(email);
		if (user == null) {
			// mvc.addObject("sysInfo", "不存在该用户");
			// mvc.setViewName(ViewPaths.LOGIN_VIEW);
			return "USER_NOT_EXISTS";
		} else {
			// 用户存在且密码匹配
			if (user.getPassword().equals(password)) {
				if (user.getActivity() == Activity.NORMAL) {
					// 把user放入session中
					WebHelper.setSessionAttribute(Constants.SESSION_USER, user);
					// mvc.setViewName("redirect:" + ViewPaths.HOME_VIEW
					// + ViewPaths.SUFFIX);
					String beforLoginUrl = WebHelper
							.getSessionAttribute(Constants.SESSION_BEFORE_LOGIN_URL);

					// 更新用户登入时间 ip
					userService.changeLoginUserInfo(user.getId());

					if (beforLoginUrl != null) {
						WebHelper
								.removeSessionAttribute(Constants.SESSION_BEFORE_LOGIN_URL);
						return "SUCCESS?" + beforLoginUrl;
					}

					return "SUCCESS";
				}
				// 未激活用户
				else if (user.getActivity() == Activity.INACTIVE) {
					// 存在着老的激活注册信息
					Ticket ticket = WebHelper.getSessionAttribute(null,
							Constants.SESSION_ACTIVE_USER_TICKET);
					// 如果ticket无效的话，就再次发送
					if (ticket != null
							&& !WebHelper.isTicketSessionValid(null,
									Constants.SESSION_ACTIVE_USER_TICKET)) {
						// session里的ticket会被再次覆盖
						userBaseService.activeUserReturnWithUrl(email,
								user.getIdNumber());
					}
					// 不存在ticket
					else if (ticket == null) {
						userBaseService.activeUserReturnWithUrl(email,
								user.getIdNumber());
					}
					// 其他情况不用再发送激活信息
					else {

					}

					// mvc.setViewName(ViewPaths.ACTIVE_VIEW);
					// mvc.addObject("sysInfo",
					// "你的账号未激活,请到注册邮箱'" + user.getEmail() + "'中激活");
					return "USER_NOT_ACTIVED";
				}
				//用户被冻结
				else if(user.getActivity()==Activity.FREEZED){
					return "FREEZED";
				}
			}
			else {
				// mvc.addObject("sysInfo", "用户或密码错误");
				// mvc.setViewName(ViewPaths.LOGIN_VIEW);
				return "FAILED";
			}
		}

		return "ERROR";
	}

	/**
	 * 用户登出
	 * 
	 * @return
	 */
	@RequestMapping(value = "/logout", method = RequestMethod.GET)
	public ModelAndView logout() {
		logger.info("user logout----->");

		// 将用户信息从缓存中移除
		User user = WebHelper.getSessionUser();
		MessageRemainsHelper.removeRemains(user.getId());
		WebHelper.invalidateSession(null);

		ModelAndView mvc = new ModelAndView();
		mvc.addObject("sysInfo", "登 出 成 功");
		mvc.setViewName(ViewPaths.LOGIN_VIEW);

		return mvc;
	}

	/**
	 * 注册
	 * 
	 * @return
	 */
	@RequestMapping(value = "/register", method = RequestMethod.GET)
	public ModelAndView registerRequest() {
		logger.info("register Request----->");

		ModelAndView mvc = new ModelAndView();
		// mvc.setViewName(ViewPaths.REGISTER_VIEW);

		return mvc;
	}

	/**
	 * 注册成功后，显示要用户激活信息
	 * 
	 * @param nickname
	 * @param email
	 * @param password
	 * @param idNumber
	 * @param realName
	 * @param sex
	 * @param role
	 * @return
	 */
	@RequestMapping(value = "/register", method = RequestMethod.POST)
	public @ResponseBody
	String registerExecute(String nickname, String email, String password,
			String idNumber, String realName, String sex, String role,
			String major, String safeFactor) {
		logger.info("registerExecute----->sex=" + sex + "   role=" + role);
		long id = 0;

		// 医生
		if ("DOCTOR".equals(role)) {
			id = userBaseService.register(nickname, email, password, idNumber,
					realName, sex, role, major, safeFactor);
		}
		// 普通用户
		else {
			id = userBaseService.register(nickname, email, password, idNumber,
					realName, sex, role, "", safeFactor);
		}

		// ModelAndView mvc = new ModelAndView();
		if (id > 0) {
			String result = userBaseService.activeUserReturnWithUrl(email,
					idNumber);
			if (result.equals("")) {
				return "FAILED";
			} else {
				//标记有更新
				AllNicknamesAndUID.flag=true;
				return "SUCCESS";
			}
			// mvc.setViewName(ViewPaths.ACTIVE_VIEW);

		} else {
			// mvc.setViewName("redirect:" + ViewPaths.ERROR_VIEW);
			return "ERROR";
		}

	}

	/**
	 * 激活注册帐号
	 * 
	 * @return
	 */
	@RequestMapping(value = "/active", method = RequestMethod.GET)
	public ModelAndView activeUserRequest(String uuid) {
		logger.info("激活用户信息请求----->");
		ModelAndView mvc = new ModelAndView();
		mvc.setViewName(ViewPaths.ACTIVE_VIEW);

		Ticket ticket = WebHelper
				.getSessionAttribute(Constants.SESSION_ACTIVE_USER_TICKET);

		// 用户可能在别的浏览器登入邮箱，导致session为空,所以重新从数据库取出
		if (ticket == null) {
			ticket = ticketService.getTicketByUUID(uuid);
			// 还是为空，说明无效
			if (ticket == null) {
				mvc.addObject("sysInfo", "该链接无效");
				return mvc;
			}
		}

		// 返回: 无效-1;过期0;有效1;帐号已激活2
		int valid = ticketService.isValid(uuid);

		if (valid == 2) {
			mvc.addObject("sysInfo", "您的帐号已激活，无须重新激活");
			return mvc;
		}

		else if (valid == 1) {
			// 激活用户
			userBaseService.activeUser(ticket.getUserId());
			// // 从session中移除
			// WebHelper.removeSessionAttribute(null,
			// Constants.SESSION_ACTIVE_USER_TICKET);
			// 删除ticket数据库
			ticketService.deleteTicket(ticket.getId());

			// TODO 用户激活之后，初始化相应的数据库：idolfan,fund等
			userService.initUser(ticket.getUserId());

			mvc.addObject("sysInfo",
					"帐号成功激活，请<a href='../base/login.html'> 登入 </a>。");

		} else if (valid == 0) {
			User user = userService.getUserById(ticket.getUserId());
			mvc.addObject(
					"sysInfo",
					"激活链接已过期,请重新发送<br><br><br>"
							+ "<input type='button' value='重新发送' id='reSendUUID' name='reSendUUID' onclick=reSend("
							+ user.getId() + ",'" + user.getEmail() + "','"
							+ user.getIdNumber() + "') />");
			// 无效-1
		} else {
			mvc.addObject("sysInfo", "该链接无效");
		}

		return mvc;
	}

	/**
	 * 重新发送激活信息
	 * 
	 * @param userId
	 * @param email
	 * @return
	 */
	@RequestMapping(value = "/reSend", method = RequestMethod.POST)
	public @ResponseBody
	String reSendUUID(long userId, String idNumber, String email) {
		logger.info("重新发送激活帐号信息--请求:" + userId + " " + idNumber + " " + email);

		String result = userBaseService.activeUserReturnWithUrl(email.trim(),
				idNumber.trim());
		if (result.equals("")) {
			return "FAILED";
		} else {
			logger.info("重新发送激活帐号信息成功");
			return "SUCCESS";
		}

	}

	/**
	 * 请求找回密码
	 * 
	 * @return
	 */
	@RequestMapping(value = "/findPasswd", method = RequestMethod.GET)
	public ModelAndView findPasswdRequest() {
		logger.info("找回密码请求----->");

		ModelAndView mvc = new ModelAndView();
		mvc.setViewName(ViewPaths.FINDPASSWD_VIEW);

		return mvc;
	}

	/**
	 * 返回修改密码的URL<br>
	 * 有效性为24小时
	 * 
	 * @param email
	 * @param idNumber
	 * @return
	 */
	@RequestMapping(value = "findPasswd", method = RequestMethod.POST)
	public @ResponseBody
	boolean findPasswdExecute(String email, String idNumber) {
		logger.info("找回密码处理----->");

		// 已成功向指定邮箱发送激活链接
		if (!userBaseService.findPasswdReturnWithUrl(email, idNumber)
				.equals("")) {
			return true;
		} else {
			return false;
		}

	}

	/**
	 * 用户无法登入<br>
	 * 直接忘记密码<br>
	 * 通过URL修改密码 验证通过后到修改密码界面
	 * 
	 * @return
	 */
	@RequestMapping(value = "/modifyForgetPasswd", method = RequestMethod.GET)
	public ModelAndView modifyForgetPasswdRequest(String uuid) {
		ModelAndView mvc = new ModelAndView();
		// 借用激活页面
		mvc.setViewName(ViewPaths.ACTIVE_VIEW);

		Ticket ticket = WebHelper.getSessionAttribute(null,
				Constants.SESSION_FIND_PASSWD_TICKET);
		if (ticket == null) {
			mvc.addObject("sysInfo", "链接无效");
			return mvc;
		}

		int valid = ticketService.isValid(uuid);

		if (valid == 1) {
			mvc.setViewName(ViewPaths.MODIFYFORGETPASSWD_VIEW);
		} else if (valid == 0) {
			mvc.addObject("sysInfo", "激活链接已过期,请重新发送");
			// 无效-1
		} else {
			mvc.addObject("sysInfo", "链接无效,请重新发送");
		}

		return mvc;
	}

	/**
	 * 修改密码成功后返回到登入界面
	 * 
	 * @param uuid
	 * @return
	 */
	@RequestMapping(value = "/modifyForgetPasswd", method = RequestMethod.POST)
	public ModelAndView modifyForgetPasswdExecute(String password) {
		Ticket ticket = WebHelper.getSessionAttribute(null,
				Constants.SESSION_FIND_PASSWD_TICKET);
		// 防止恶意修改
		if (ticket == null) {
			throw new NotOperationEexception();
		}

		ModelAndView mvc = new ModelAndView();
		userBaseService.modifyPasswd(ticket.getUserId(), password);
		mvc.addObject("sysInfo", "修 改  成 功");
		// 移除并删除数据库记录,SESSION
		WebHelper.removeSessionAttribute(null,
				Constants.SESSION_FIND_PASSWD_TICKET);
		ticketService.deleteTicket(ticket.getId());

		mvc.setViewName(ViewPaths.LOGIN_VIEW);

		return mvc;
	}

	/**
	 * 检查邮箱是否存在,是否被注册
	 * 
	 * @param email
	 * @return -1->邮箱已被注册<br>
	 *         0->邮箱真实不存在<br>
	 *         1->邮箱可用
	 * @throws DNSLookupException
	 */
	@SuppressWarnings("deprecation")
	@RequestMapping(value = "/isEmailExist", method = RequestMethod.POST)
	public @ResponseBody
	int isEmailExist(String email) throws DNSLookupException {
		User user = userBaseService.isUserExist(email);
		if (user != null) {
			return -1;
		}
		return MailHelper.checkEmail(email) == true ? 1 : 0;
	}

	/**
	 * 存在："true" 不存在："false"
	 * 
	 * @param nickname
	 * @return
	 */
	@RequestMapping(value = "/isNicknameExist", method = RequestMethod.POST)
	public @ResponseBody
	String isNicknameExist(String nickname) {
		boolean result = userBaseService.isNicknameExist(nickname);
		if (result) {
			return "true";
		} else {
			return "false";
		}
	}

	/**
	 * 生成随机图片
	 * 
	 * @param request
	 * @param response
	 */
	@RequestMapping(value = "/getCertCode")
	public void getCertCode(HttpServletRequest request,
			HttpServletResponse response) {
		try {
			// 设置不缓存图片
			response.setHeader("Prama", "No-cache");
			response.setHeader("Cache-Control", "No-cache");
			response.setDateHeader("Expires", 0);
			// 格式
			response.setContentType("image/jpeg");
			BufferedImage image = CertCodeHelper.getCertCodeImage(20, 5);
			ImageIO.write(image, "JPEG", response.getOutputStream());
			WebHelper.setSessionAttribute(request, Constants.SESSION_CERT_CODE,
					CertCodeHelper.getCertCode());
			logger.info("生成验证码:" + CertCodeHelper.getCertCode());
		} catch (Exception e) {
			logger.warn("生成验证码出错");
		}
	}

	/**
	 * 核对验证码
	 * 
	 * @return
	 */
	@RequestMapping(value = "/checkCertCode", method = RequestMethod.POST)
	public @ResponseBody
	String checkCertCode(String certCode) {
		String cert = WebHelper
				.getSessionAttribute(Constants.SESSION_CERT_CODE);
		if (cert != null && !cert.equals("")) {
			if (cert.toLowerCase().equals(certCode.toLowerCase())) {
				return "true";
			}
		}
		return "false";
	}

	/**
	 * 关于我们的页面
	 * 
	 * @return
	 */
	@RequestMapping(value = "/about", method = RequestMethod.GET)
	public ModelAndView about() {
		ModelAndView mvc = new ModelAndView();

		User user = WebHelper.getSessionAttribute(Constants.SESSION_USER);
		if (user != null) {
			int messageCount = MessageRemainsHelper.getRemains(user.getId());
			mvc.addObject("messageCount", messageCount);
		}
		mvc.addObject("user", user);
		mvc.setViewName(ViewPaths.ABOUT_INDEX);

		return mvc;
	}

	/**
	 * 详情信息 错误提醒
	 * 
	 * @param info
	 * @return
	 */
	@RequestMapping(value = "/info", method = RequestMethod.GET)
	public ModelAndView info(String info) {
		ModelAndView mvc = new ModelAndView();

		mvc.setViewName(ViewPaths.INFO_VIEW);
		mvc.addObject("sysInfo", info);

		return mvc;
	}

	/**
	 * 得到"关于我们" 最新的一条<br>
	 * 更新需要超级管理员权限:superController<br>
	 * 
	 * @return
	 */
	@RequestMapping(value = "/about/get", method = RequestMethod.POST)
	public @ResponseBody
	String updateAbout() {
		String content = AboutContentHelper.getContent();

		return content;
	}

	/**
	 * 鼠标测试
	 * 
	 * @return
	 */
	@RequestMapping(value = "/mouseTest")
	public ModelAndView mouseTest() {
		ModelAndView mvc = new ModelAndView();
		mvc.setViewName("/base/mouseTest");
		return mvc;
	}

	@RequestMapping(value = "/getUser", method = RequestMethod.POST)
	public @ResponseBody
	User getUserById(long userId) {
		User user = userBaseService.getUserById(userId);
		return user;
	}
}
